
#include "Font.h"
#include "TextureManager.h"
#include "../Settings.h"

#include <string>
#include <GL/gl.h>


Font::Font(std::string font_filename, float size, float letter_spacing) :
    size(size), letter_spacing(letter_spacing) {

    font_texture_id = TextureManager::instance().loadTexture(font_filename);

    if(Settings::instance().getIntValue("graphics", "render")){
        generateDisplayLists();
    }
}

Font::~Font(){
    // TODO: do i need to free or inform the texture manager im not really
    // using the font texture anymore?
	glDeleteLists(letter_display_list_base, 256);
}

void Font::renderString(std::string text){
    // Draw each letter of the string, specifying the colour and the position of each.
    TextureManager::instance().bindTexture(font_texture_id);
    glEnable(GL_TEXTURE_2D);

    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.0f);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    for(unsigned i = 0; i < text.size(); i++){
        glPushMatrix();

        glTranslatef(i*letter_spacing, 0.0f, 0.0f);
        glScalef(size, size, size);
        glCallList(letter_display_list_base + (unsigned int)text[i]);

        glPopMatrix();
	}

    glDisable(GL_BLEND);
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_TEXTURE_2D);
}

void Font::generateDisplayLists(void){
    const float tex_coord_traversal = 16.0f/256.0f;

    // Loop through all 256 cells of the font texture file and generate
	// a GL Display List for each letter.
    letter_display_list_base = glGenLists(256);
    glListBase(letter_display_list_base);
    for(unsigned y = 0; y < 16; y++){
        for(unsigned x = 0; x < 16; x++){
            glNewList(letter_display_list_base + y*16 + x, GL_COMPILE);
            glBegin(GL_QUADS);
              glTexCoord2f(x*tex_coord_traversal,     (y+1)*tex_coord_traversal);     glVertex2f(-0.5f, -0.5f);
              glTexCoord2f(x*tex_coord_traversal,     y*tex_coord_traversal);	        glVertex2f(-0.5f, 0.5f);
              glTexCoord2f((x+1)*tex_coord_traversal, y*tex_coord_traversal);	        glVertex2f(0.5f, 0.5f);
              glTexCoord2f((x+1)*tex_coord_traversal, (y+1)*tex_coord_traversal);     glVertex2f(0.5f, -0.5f);
            glEnd();
            glEndList();
        }
    }
}

